package com.dms.modules.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dms.common.exception.BusinessException;

import com.dms.modules.merchant.entity.Merchant;
import com.dms.modules.merchant.mapper.MerchantMapper;
import com.dms.modules.merchant.service.MerchantService;
import com.dms.modules.product.service.ProductService;
import com.dms.modules.system.service.RoleUserService;
import com.dms.modules.user.entity.User;
import com.dms.modules.user.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.TimeUnit;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Collections;
import java.util.stream.Collectors;

import com.dms.modules.merchant.vo.ShopDisplayVO;
import com.dms.modules.merchant.dto.ShopQueryDTO;
import com.dms.modules.merchant.cache.ShopCacheManager;
import com.dms.modules.product.vo.ProductVO;
import com.dms.modules.product.entity.Product;
import org.springframework.security.core.context.SecurityContextHolder;
import java.math.BigDecimal;
import com.dms.common.security.SecurityUtils;
import com.dms.modules.product.entity.ProductFavorite;
import com.dms.modules.product.service.ProductFavoriteService;
import com.dms.modules.merchant.vo.MerchantShopVO;

/**
 * 商户服务实现类
 */
@Slf4j
@Service
public class MerchantServiceImpl extends ServiceImpl<MerchantMapper, Merchant> implements MerchantService, UserDetailsService {

    private static final int MERCHANT_USER_TYPE = 2; // 商家用户类型
    private static final String DEFAULT_PASSWORD = "123456";

    @Autowired
    private ProductService productService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private RoleUserService userRoleService;
    
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ShopCacheManager shopCacheManager;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ProductFavoriteService productFavoriteService;

    public MerchantServiceImpl(PasswordEncoder passwordEncoder, RoleUserService userRoleService) {
        this.passwordEncoder = passwordEncoder;
        this.userRoleService = userRoleService;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Merchant merchant = getByUsername(username);
        if (merchant == null) {
            throw new UsernameNotFoundException("商户不存在");
        }
        return merchant;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createMerchant(Merchant merchant) {
        // 检查用户名是否已存在
        if (getByUsername(merchant.getUsername()) != null) {
            throw new BusinessException("用户名已存在");
        }
        
        // 检查手机号是否已存在
        if (StringUtils.hasText(merchant.getPhone())) {
            User existUserByPhone = userMapper.selectOne(new LambdaQueryWrapper<User>()
                    .eq(User::getPhone, merchant.getPhone()));
            if (existUserByPhone != null) {
                throw new BusinessException("该手机号已被注册，请使用其他手机号");
            }
        }
        
        // 如果指定了关联的用户ID，则检查并更新用户角色
        if (merchant.getUserId() != null) {
            User user = userMapper.selectById(merchant.getUserId());
            if (user == null) {
                throw new BusinessException("关联的用户不存在");
            }
            
            // 更新用户角色为商家
            user.setRoleId(2L); // 2-商家角色
            userMapper.updateById(user);
        } else {
            // 如果没有指定关联用户，则创建新用户并关联
            User user = new User();
            user.setUsername(merchant.getUsername());
            user.setPassword(merchant.getPassword()); // 密码会在下面加密
            user.setNickname(merchant.getNickname());
            user.setAvatar(merchant.getAvatar());
            user.setEmail(merchant.getEmail());
            user.setPhone(merchant.getPhone());
            user.setStatus(1);
            user.setRoleId(2L); // 2-商家角色
            
            // 加密密码
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            userMapper.insert(user);
            
            // 设置商家关联的用户ID
            merchant.setUserId(user.getId());
        }
        
        // 设置默认密码
        merchant.setPassword(passwordEncoder.encode(DEFAULT_PASSWORD));
        // 设置默认状态
        merchant.setStatus(1);
        
        return save(merchant);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMerchant(Merchant merchant) {
        // 检查商家是否存在
        Merchant existingMerchant = getById(merchant.getId());
        if (existingMerchant == null) {
            throw new BusinessException("商家不存在");
        }
        
        // 更新商家信息
        return updateById(merchant);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteMerchant(Long id) {
        // 检查商家是否存在
        Merchant merchant = getById(id);
        if (merchant == null) {
            throw new BusinessException("商家不存在");
        }
        
        return removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(Long id, Integer status) {
        // 检查商家是否存在
        Merchant merchant = getById(id);
        if (merchant == null) {
            throw new BusinessException("商家不存在");
        }
        
        merchant.setStatus(status);
        return updateById(merchant);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetPassword(Long id) {
        Merchant merchant = getById(id);
        if (merchant == null) {
            throw new BusinessException("商家不存在");
        }
        merchant.setPassword(passwordEncoder.encode(DEFAULT_PASSWORD));
        return updateById(merchant);
    }

    @Override
    public Merchant getByUsername(String username) {
        return baseMapper.selectByUsername(username);
    }

    @Override
    public IPage<Merchant> getMerchantPage(Page<Merchant> page, String keyword) {
        LambdaQueryWrapper<Merchant> wrapper = new LambdaQueryWrapper<>();
        // 只查询审核通过的商家
        wrapper.eq(Merchant::getAuditStatus, 1);
        
        if (keyword != null && !keyword.isEmpty()) {
            wrapper.and(w -> w
                    .like(Merchant::getShopName, keyword)
                    .or()
                    .like(Merchant::getContactPhone, keyword)
                    .or()
                    .like(Merchant::getContactEmail, keyword)
                    .or()
                    .like(Merchant::getAddress, keyword));
        }
        wrapper.orderByDesc(Merchant::getCreateTime);
        
        // 执行分页查询
        IPage<Merchant> merchantPage = page(page, wrapper);
        
        // 补充用户信息
        if (merchantPage.getRecords() != null && !merchantPage.getRecords().isEmpty()) {
            for (Merchant merchant : merchantPage.getRecords()) {
                if (merchant.getUserId() != null) {
                    User user = userMapper.selectById(merchant.getUserId());
                    if (user != null) {
                        merchant.setUsername(user.getUsername());
                        merchant.setNickname(user.getNickname());
                        merchant.setAvatar(user.getAvatar());
                        merchant.setEmail(user.getEmail());
                        merchant.setPhone(user.getPhone());
                    }
                }
            }
        }
        
        return merchantPage;
    }

    @Override
    public boolean assignRoles(Long merchantId, List<Long> roleIds) {
        if (roleIds == null || roleIds.isEmpty()) {
            log.warn("没有角色ID被分配给商家 merchantId={}", merchantId);
            return true;
        }
        
        // 获取商家信息
        Merchant merchant = getById(merchantId);
        if (merchant == null || merchant.getUserId() == null) {
            log.warn("商家不存在或未关联用户 merchantId={}", merchantId);
            return false;
        }
        
        // 只取第一个角色ID
        Long roleId = roleIds.get(0);
        
        // 更新用户角色
        return updateUserRole(merchant.getUserId(), roleId);
    }

    @Override
    public List<Long> getRoleIds(Long merchantId) {
        // 获取商家信息
        Merchant merchant = getById(merchantId);
        if (merchant == null || merchant.getUserId() == null) {
            return Collections.emptyList();
        }
        
        // 获取用户信息
        User user = userMapper.selectById(merchant.getUserId());
        if (user == null || user.getRoleId() == null) {
            return Collections.emptyList();
        }
        
        return Collections.singletonList(user.getRoleId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long applyMerchant(Long userId, com.dms.modules.user.dto.MerchantApplyDTO applyDTO) {
        // 参数校验
        if (!StringUtils.hasText(applyDTO.getShopName())) {
            throw new BusinessException("店铺名称不能为空");
        }
        if (!StringUtils.hasText(applyDTO.getBusinessLicense())) {
            throw new BusinessException("营业执照号不能为空");
        }
        if (!StringUtils.hasText(applyDTO.getLegalPerson())) {
            throw new BusinessException("法人姓名不能为空");
        }
        
        // 检查店铺名称是否已存在
        Merchant existMerchant = lambdaQuery()
            .eq(Merchant::getShopName, applyDTO.getShopName())
            .one();
        if (existMerchant != null) {
            throw new BusinessException("店铺名称已存在");
        }
        
        // 创建商家信息
        Merchant merchant = new Merchant();
        BeanUtils.copyProperties(applyDTO, merchant);
        merchant.setUserId(userId);
        merchant.setStatus(1);
        merchant.setAuditStatus(0);
        merchant.setCreateTime(new Date());
        merchant.setUpdateTime(new Date());
        
        // 保存商家信息
        save(merchant);
        
        return merchant.getId();
    }

    @Override
    public void updateLoginInfo(Long id, String ip) {
        Merchant merchant = getById(id);
        if (merchant != null) {
            // 更新商家信息，例如最后登录时间等
            merchant.setUpdateTime(new Date());
            updateById(merchant);
            
            // 可以在这里记录登录日志
            log.info("商家ID: {}, IP: {} 登录成功", id, ip);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserRole(Long userId, Long roleId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            log.warn("用户不存在，userId={}", userId);
            return false;
        }
        
        // 直接更新用户的role_id字段
        user.setRoleId(roleId);
        int result = userMapper.updateById(user);
        
        log.info("已更新用户角色 userId={}, roleId={}", userId, roleId);
        return result > 0;
    }

    @Override
    public List<Merchant> getNonApprovedMerchants() {
        // 构建查询条件：审核状态不为1（非审核通过，包括待审核和已拒绝）
        LambdaQueryWrapper<Merchant> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(Merchant::getAuditStatus, 1)  // 审核状态不为1（非审核通过）
              .orderByDesc(Merchant::getCreateTime);  // 按创建时间倒序排序
        
        // 执行查询
        List<Merchant> merchants = this.list(wrapper);
        
        // 补充用户信息
        if (merchants != null && !merchants.isEmpty()) {
            for (Merchant merchant : merchants) {
                if (merchant.getUserId() != null) {
                    User user = userMapper.selectById(merchant.getUserId());
                    if (user != null) {
                        merchant.setUsername(user.getUsername());
                        merchant.setNickname(user.getNickname());
                        merchant.setAvatar(user.getAvatar());
                        merchant.setEmail(user.getEmail());
                        merchant.setPhone(user.getPhone());
                    }
                }
            }
        }
        
        return merchants;
    }

    @Override
    public List<Merchant> searchMerchants(String keyword) {
        if (!StringUtils.hasText(keyword)) {
            return Collections.emptyList();
        }
        
        LambdaQueryWrapper<Merchant> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Merchant::getUsername, keyword)
            .or()
            .like(Merchant::getShopName, keyword)
            .or()
            .like(Merchant::getContactPhone, keyword)
            .or()
            .like(Merchant::getAddress, keyword);
            
        return list(wrapper);
    }

    @Override
    public Merchant getByUserId(Long userId) {
        if (userId == null) {
            return null;
        }
        return baseMapper.selectOne(
            new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getUserId, userId)
                .eq(Merchant::getDeleted, 0)
        );
    }

    @Override
    public IPage<ShopDisplayVO> getShopList(ShopQueryDTO queryDTO) {
        // 构建查询条件
        LambdaQueryWrapper<Merchant> wrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            wrapper.like(Merchant::getShopName, queryDTO.getKeyword())
                .or()
                .like(Merchant::getShopDescription, queryDTO.getKeyword());
        }
        
        // 评分筛选
        if (queryDTO.getMinScore() != null) {
            wrapper.ge(Merchant::getScore, queryDTO.getMinScore());
        }
        
        // 是否只看推荐
        if (queryDTO.getOnlyRecommend() != null && queryDTO.getOnlyRecommend() == 1) {
            wrapper.eq(Merchant::getIsRecommend, 1);
        }
        
        // 排序处理
        if (StringUtils.hasText(queryDTO.getSortField())) {
            boolean isAsc = "asc".equalsIgnoreCase(queryDTO.getSortOrder());
            switch (queryDTO.getSortField()) {
                case "score":
                    wrapper.orderBy(true, isAsc, Merchant::getScore);
                    break;
                case "time":
                    wrapper.orderBy(true, isAsc, Merchant::getCreateTime);
                    break;
                default:
                    wrapper.orderBy(true, false, Merchant::getCreateTime);
            }
        } else {
            wrapper.orderByDesc(Merchant::getCreateTime);
        }
        
        // 状态正常且审核通过的商家
        wrapper.eq(Merchant::getStatus, 1)
            .eq(Merchant::getAuditStatus, 1);
        
        // 分页查询
        Page<Merchant> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        IPage<Merchant> merchantPage = page(page, wrapper);
        
        // 转换为VO
        IPage<ShopDisplayVO> shopVOPage = new Page<>(merchantPage.getCurrent(), merchantPage.getSize(), merchantPage.getTotal());
        List<ShopDisplayVO> shopVOList = merchantPage.getRecords().stream().map(merchant -> {
            ShopDisplayVO shopVO = convertToShopDisplayVO(merchant);
            // 实时获取统计数据
            shopVO.setMonthlySales(getMonthlySales(merchant.getId()));
            shopVO.setTotalSales(getTotalSales(merchant.getId()));
            shopVO.setProductCount(getProductCount(merchant.getId()));
            return shopVO;
        }).collect(Collectors.toList());
        
        shopVOPage.setRecords(shopVOList);
        return shopVOPage;
    }
    
    @Override
    public ShopDisplayVO getShopDetail(Long id) {
        // 获取商家信息
        Merchant merchant = getById(id);
        if (merchant == null) {
            throw new BusinessException("店铺不存在");
        }
        
        ShopDisplayVO shopVO = convertToShopDisplayVO(merchant);
        
        // 实时获取统计数据
        shopVO.setMonthlySales(getMonthlySales(id));
        shopVO.setTotalSales(getTotalSales(id));
        shopVO.setProductCount(getProductCount(id));
        
        return shopVO;
    }
    
    @Override
    public IPage<ProductVO> getShopProducts(Long shopId, Integer pageNum, Integer pageSize, Long categoryId) {
        // 验证店铺是否存在且正常营业
        Merchant merchant = getById(shopId);
        if (merchant == null || merchant.getDeleted() == 1 || merchant.getStatus() != 1) {
            throw new BusinessException("店铺不存在或已关闭");
        }
        
        // 构建商品查询条件
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<Product>()
                .eq(Product::getMerchantId, shopId)
                .eq(Product::getStatus, 1)
                .eq(Product::getDeleted, 0);
        
        if (categoryId != null) {
            wrapper.eq(Product::getCategoryId, categoryId);
        }
        
        // 执行分页查询
        Page<Product> page = new Page<>(pageNum, pageSize);
        IPage<Product> productPage = productService.page(page, wrapper);
        
        // 获取当前登录用户ID（如果已登录）
        Long currentUserId = null;
        try {
            currentUserId = SecurityUtils.getCurrentUserId();
        } catch (Exception e) {
            log.debug("用户未登录");
        }
        
        // 转换为VO，并确保所有必要字段都有值
        Long finalCurrentUserId = currentUserId;
        return productPage.convert(product -> {
            ProductVO vo = new ProductVO();
            BeanUtils.copyProperties(product, vo);
            
            // 设置商品主图
            if (!StringUtils.hasText(vo.getMainImage())) {
                vo.setMainImage(StringUtils.hasText(product.getMainImage()) ? 
                    product.getMainImage() : "/default-product.jpg");
            }
            
            // 设置商品描述
            if (!StringUtils.hasText(vo.getDescription())) {
                vo.setDescription(product.getName());
            }
            
            // 设置商品状态
            vo.setStatus(product.getStatus());
            
            // 设置商品价格
            if (vo.getPrice() == null) {
                vo.setPrice(BigDecimal.ZERO);
            }
            
            // 设置是否收藏（如果当前用户已登录）
            if (finalCurrentUserId != null) {
                vo.setFavorite(productFavoriteService.isFavorite(finalCurrentUserId, product.getId()));
                if (Boolean.TRUE.equals(vo.getFavorite())) {
                    // 获取收藏记录
                    IPage<ProductFavorite> favorites = productFavoriteService.getUserFavorites(
                        finalCurrentUserId, 1, 1);
                    if (favorites != null && !favorites.getRecords().isEmpty()) {
                        vo.setFavoriteTime(favorites.getRecords().get(0).getCreateTime());
                    }
                }
            } else {
                vo.setFavorite(false);
            }
            
            return vo;
        });
    }
    
    private ShopDisplayVO convertToShopDisplayVO(Merchant merchant) {
        if (merchant == null) {
            return null;
        }
        
        ShopDisplayVO vo = new ShopDisplayVO();
        BeanUtils.copyProperties(merchant, vo);
        return vo;
    }

    @Override
    public int getMonthlySales(Long merchantId) {
        return baseMapper.getMonthlySales(merchantId);
    }
    
    @Override
    public int getTotalSales(Long merchantId) {
        return baseMapper.getTotalSales(merchantId);
    }
    
    @Override
    public int getProductCount(Long merchantId) {
        return baseMapper.getProductCount(merchantId);
    }

    @Override
    public MerchantShopVO getShopInfo(Long merchantId) {
        // 获取商家信息
        Merchant merchant = getById(merchantId);
        if (merchant == null) {
            throw new BusinessException("商家不存在");
        }

        // 转换为VO
        MerchantShopVO vo = new MerchantShopVO();
        BeanUtils.copyProperties(merchant, vo);
        
        // 如果商家联系方式为空，从用户表获取
        if (!StringUtils.hasText(vo.getContactPhone()) || !StringUtils.hasText(vo.getContactEmail())) {
            User user = userMapper.selectById(merchant.getUserId());
            if (user != null) {
                if (!StringUtils.hasText(vo.getContactPhone())) {
                    vo.setContactPhone(user.getPhone());
                }
                if (!StringUtils.hasText(vo.getContactEmail())) {
                    vo.setContactEmail(user.getEmail());
                }
            }
        }
        
        // 获取实时统计数据
        vo.setMonthlySales(getMonthlySales(merchantId));
        vo.setTotalSales(getTotalSales(merchantId));
        vo.setProductCount(getProductCount(merchantId));
        
        return vo;
    }
} 